/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.tchepannou.limbe.interceptor;

import com.tchepannou.limbe.Controller;
import com.tchepannou.limbe.Interceptor;
import com.tchepannou.limbe.User;
import com.tchepannou.limbe.annotation.RequireUser;
import com.tchepannou.limbe.web.ActionController;

import java.io.IOException;
import java.lang.reflect.Method;

/**
 * This interceptor handle the annotation {@link RequireUser}.
 * If the annotation {@link RequireUser} is set on a class or method and there are no current user,
 * this interceptor will return the HTTP error 401.
 * 
 * @author herve
 */
public class RequireUserInterceptor
    implements Interceptor
{
    //-- Interceptor
    @Override
    public int before (Controller controller)
    {
        try
        {
            if ( controller instanceof ActionController )
            {
                RequireUser annotation = controller.getClass ().getAnnotation (RequireUser.class);
                if ( annotation != null )
                {
                    return checkSecurity (annotation, ( ActionController ) controller);
                }
            }
            return Interceptor.CONTINUE;
        }
        catch ( IOException e )
        {
            throw new IllegalStateException ("IO Error", e);
        }
    }

    @Override
    public int before (Method method, Controller controller)
    {
        try
        {
            if ( controller instanceof ActionController )
            {
                RequireUser annotation = method.getAnnotation (RequireUser.class);
                if ( annotation != null )
                {
                    return checkSecurity (annotation, ( ActionController ) controller);
                }
            }
            return Interceptor.CONTINUE;
        }
        catch ( IOException e )
        {
            throw new IllegalStateException ("IO Error", e);
        }
    }

    @Override
    public void after (Method method, Controller controller, Throwable e)
    {
    }

    @Override
    public void after (Controller controller)
    {
    }

    //-- Protected methods
    protected int checkSecurity (RequireUser annotation, ActionController controller)
        throws IOException
    {
        if ( annotation != null )
        {
            User user = controller.getCurrentUser ();
            if ( user == null )
            {
                fail(controller);
                return Interceptor.STOP;
            }
        }
        return Interceptor.CONTINUE;
    }
    
    protected void fail (ActionController controller)
        throws IOException
    {
        controller.getResponse ().sendError (401);
    }
}
